package com.zlyx.easy.core.utils;

import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import com.zlyx.easy.core.annotations.SpringBean;
import com.zlyx.easy.core.event.IHandlerOnChanged;
import com.zlyx.easy.core.map.SafeMap;
import com.zlyx.easy.core.tool.Ops;

/**
 * @Auth 赵光
 * @Desc 线程池自动化管理工具
 * @2018年12月12日 下午2:19:03
 */
@SpringBean(todo = { "线程管理中心" })
public class ThreadManager implements IHandlerOnChanged {

	private static SafeMap<Runnable> threads = SafeMap.newMap();

	private static ExecutorService threadPool;

	public ThreadManager(@Autowired(required = false) ExecutorService threadPool) {
		if (threadPool == null) {
			threadPool = Executors.newCachedThreadPool();
		}
		ThreadManager.threadPool = threadPool;
	}

	/**
	 * 分配一个线程执行任务
	 * 
	 * @param thread
	 * @return
	 */
	public static Thread execute(Runnable runnable) {
		Thread thread = new Thread(runnable);
		return execute(thread);
	}

	/**
	 * 分配一个线程执行任务
	 * 
	 * @param thread
	 * @return
	 */
	public static Thread execute(Thread thread) {
		return execute(thread, Ops.getStatus(thread));
	}

	/**
	 * 分配一个线程执行任务
	 * 
	 * @param thread
	 * @return
	 */
	public static Runnable execute(Runnable runnable, String threadName) {
		if (isActive()) {
			threadPool.execute(runnable);
			threads.put(threadName, runnable);
		}
		return runnable;
	}

	/**
	 * 分配一个线程执行任务
	 * 
	 * @param name
	 * @param command
	 * @return
	 */
	public static Thread execute(Thread thread, String threadName) {
		if (isActive()) {
			threadPool.execute(thread);
			threads.put(threadName, thread);
		}
		return thread;
	}

	/**
	 * 根据名称获取线程
	 * 
	 * @param name
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T get(String name) {
		return (T) threads.get(name);
	}

	/**
	 * 判断某个线程是否存活
	 * 
	 * @param name
	 * @return
	 */
	public static boolean isAlive(String name) {
		Thread thread = get(name);
		if (thread != null) {
			return thread.isAlive();
		}
		return false;
	}

	/**
	 * 判断线程池是否可用
	 * 
	 * @return
	 */
	private static boolean isActive() {
		return threadPool != null && !threadPool.isShutdown();
	}

	/**
	 * 获取当前存活的所有线程的名称
	 * 
	 * @return
	 */
	public static Set<String> getNames() {
		clearDead();
		return threads.keySet();
	}

	/**
	 * 获取所有存活中的线程列表
	 * 
	 * @return
	 */
	public static SafeMap<Runnable> getThreads() {
		return threads;
	}

	/**
	 * 停止线程池
	 * 
	 * @return
	 */
	public static void shutdownNow() {
		threadPool.shutdownNow();
	}

	/**
	 * 停止线程池
	 * 
	 * @return
	 */
	public static void shutdown() {
		threadPool.shutdown();
	}

	/**
	 * 停止制定线程
	 * 
	 * @return
	 * @throws InterruptedException
	 */
	public static void stop(String name) throws InterruptedException {
		if (isAlive(name)) {
			((Thread) get(name)).interrupt();
		}
	}

	/**
	 * 清除已经死亡的线程
	 */
	public static void clearDead() {
		Set<String> names = threads.keySet();
		for (String name : names) {
			if (!isAlive(name)) {
				threads.remove(name);
			}
		}
	}

	@Override
	public void doOnChanged(ApplicationContext context) throws Exception {
		if (isActive()) {
			threads.clear();
			threadPool.shutdownNow();
		}
		threadPool = Executors.newCachedThreadPool();
	}
}
